package com.zjj.lbw.algorithm.tree;

import com.zjj.lbw.algorithm.tree.entity.TreeNode;

import java.util.*;

/**
 * @author zhanglei.zjj
 * @description leetcode_94 二叉树中序遍历
 * 给定一个二叉树的根节点 root ，返回 它的 中序 遍历 。
 *
 *
 *
 * 示例 1：
 *
 *
 * 输入：root = [1,null,2,3]
 * 输出：[1,3,2]
 * 示例 2：
 *
 * 输入：root = []
 * 输出：[]
 * 示例 3：
 *
 * 输入：root = [1]
 * 输出：[1]
 *
 *
 * 提示：
 *
 * 树中节点数目在范围 [0, 100] 内
 * -100 <= Node.val <= 100
 *
 *
 * 进阶: 递归算法很简单，你可以通过迭代算法完成吗？
 *
 * @date 2023/3/25 10:29
 */
public class BinTreeInOrderTraversal_leetcode_94 {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> resultList = new ArrayList<>();
        accessTree(root, resultList);

        return resultList;
    }

    /**
     * 递归解法
     * @param node
     * @param resultList
     */
    public void accessTree(TreeNode node, List<Integer> resultList) {
        if (Objects.isNull(node)) {
            return;
        }
        accessTree(node.left, resultList);
        resultList.add(node.val);
        accessTree(node.right, resultList);
    }

    /**
     * 循环迭代解法
     */

    public List<Integer> inorderTraversalWithLoop(TreeNode root) {
        List<Integer> resultList = new ArrayList<>();
        if (Objects.isNull(root)) {
            return resultList;
        }
        // 用list来表示栈
        Deque<TreeNode> stack = new LinkedList<>();

        stack.add(root);
        while (!stack.isEmpty()) {
            if (!Objects.isNull(root.left)) {
                root = root.left;
                stack.push(root);
                continue;
            }
            TreeNode node = stack.pop();
            resultList.add(node.val);

            if (!Objects.isNull(node.right)) {
                root = node.right;
                stack.push(root);
            }
        }
        return resultList;
    }

    public List<Integer> inorderTraversalWithLoop2(TreeNode root) {
        List<Integer> resultList = new ArrayList<>();
        if (Objects.isNull(root)) {
            return resultList;
        }
        // 用list来表示栈
        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        while (!Objects.isNull(root) || !stack.isEmpty()) {
            while (!Objects.isNull(root)) {
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            resultList.add(root.val);
            root = root.right;
        }
        return resultList;
    }
}


